
changequote([,])

define([last_id], 0)
define([next_id],[define([last_id],incr(last_id))last_id])

define([anon_prefix],anon_$1)
define([anon],[anon_prefix(next_id)])

define([car],[$1])
define([cdr],[shift($*)])

define([shift_many],[ifelse($1,0,
	[shift($*)],
	[shift_many(
		eval($1 - 1),
		[shift(shift($*))])])])

define([patch_sigp],[
# 1:id, 2:name, 3:out, 4:amp, 5:off, 6:in
ifelse([$1],,,[
# id is required
	module	proc patched_sigp_$1

	ifelse([$6],,,[ # if in is defined
		patch	patched_sigp_$1:in $6
	])
	ifelse([$5],,,[ # if offset is defined
		patch	patched_sigp_$1:off $5
	])
	ifelse([$4],,,[ # if amp is defined
		patch	patched_sigp_$1:amp $4
	])
	ifelse([$3],,,[ # if out is defined
		patch	$3 patched_sigp_$1:out
	])
	define(patched_sigp_$1_in, patched_sigp_$1:in)
	define(patched_sigp_$1_off, patched_sigp_$1:off)
	define(patched_sigp_$1_amp, patched_sigp_$1:amp)
	define(patched_sigp_$1_out, patched_sigp_$1:out)

	ifelse([$2],,,[ # if name is defined, create the aliases
		define($2_in,patched_sigp_$1_in)
		define($2_off,patched_sigp_$1_off)
		define($2_amp,patched_sigp_$1_amp)
		define($2_out,patched_sigp_$1_out)
	])
])
])

define([patch_next_r],[
# 1:iter, 2:module, ...:inputs
ifelse([$1],,,[ifelse([$2],,,[
# module and iter is required
	ifelse($3,,,[ # patch this input only if it is defined
		patch	$2:$1 $3
	])
	ifelse($#,3,,[ # recurse only if there are inputs left
		patch_next_r(eval($1 + 1),$2,shift(shift(shift($*))))
	])
])])
])

define([patch_many_by],[
# 1:id, 2:name, 3:out, 4:amp, 5:off, 6:module, 7:recordsize, ...:inputs
ifelse([$1],,,[ifelse([$6],,,[ifelse([$7],,,[
# id, module and recordsize are required
ifelse(eval($# < 8),1,,[
# there must be at least one input

	init	$6 count eval(($# - 7)/$7)
	patch_next_r(1, $6, shift_many(7, $*))
	patch_sigp($1,$2,$3,$4,$5,$6:out)
])
])])])
])

define([patch_many_type],[
# 1:id, 2:name, 3:out, 4:amp, 5:off, 6:type, ...:inputs
ifelse([$1],,,[ifelse([$6],,,[
ifelse(eval($# < 7),1,,[
	module $6 patched_many_type_$1
	patch_many_by($1,$2,$3,$4,$5,patched_many_type_$1,1,shift_many(6,$*))
])
])])
])

define([patch_sh],[
# 1:id, 2:name, 3:out, 4:amp, 5:off, 6:trigger, 7:in
ifelse([$1],,,[
# id is required
	module	sh patched_sh_$1
	init	patched_sh_$1 count 1
	ifelse([$6],,,[ # if trigger is defined
		patch	patched_sh_$1:trigger $6
	])
	ifelse([$7],,,[ # if in is defined
		patch	patched_sh_$1:1 $7
	])
	patch_sigp($1,$2,$3,$4,$5,patched_sh_$1:1)
	define(patched_sh_$1_in,patched_sh_$1:1)
	define(patched_sh_$1_trigger,patched_sh_$1:trigger)
])
])

define([patch_mixer],[
# 1:id, 2:name, 3:out, 4:amp, 5:off, ...:inputs
ifelse([$1],,,[
ifelse(eval($# < 6),1,,[
	patch_many_type($1,$2,$3,$4,$5,[add],shift_many(5,$*))
])
])
])

define([patch_mult],[
# 1:id, 2:name, 3:out, 4:amp, 5:off, ...:inputs
ifelse([$1],,,[
ifelse(eval($# < 6),1,,[
	patch_many_type($1,$2,$3,$4,$5,[mult],shift_many(5,$*))
])
])
])

define([patch_oscil],[ 
# 1:id, 2:name, 3:out, 4:amp, 5:off, 6:octave, 7:freq, 8:phase, 9:function_in 10:function_out
ifelse([$9],,,[ifelse([$10],,,[ifelse([$1],,,[
# id, function_in, and function_out are required

	define(patched_oscil_$1_oct, patched_oscil_cpsoct_$1:in)
	define(patched_oscil_$1_freq, patched_oscil_cpsoct_$1:center)
	define(patched_oscil_$1_phase, patched_oscil_ph_$1:phase)
	define(patched_oscil_$1_phasor_out, patched_oscil_ph_$1:out)

	module	cpsoct patched_oscil_cpsoct_$1
	module	phasor patched_oscil_ph_$1
	patch	patched_oscil_ph_$1:frequency patched_oscil_cpsoct_$1:out

	ifelse([$6],,,[ # if octave is defined
		patch	patched_oscil_$1_oct $6
	])
	ifelse([$7],,,[ # if frequency is defined
		patch	patched_oscil_$1_freq $7
	])
	ifelse([$8],,,[ # if phase is defined
		patch	patched_oscil_$1_phase $8
	])

	patch $9 patched_oscil_$1_phasor_out

	patch_sigp($1,$2,$3,$4,$5,$10)
	define(patched_oscil_$1_out, patched_sigp_$1_out)

	ifelse([$2],,,[ # if a name was specified, create the aliases
		define($2_oct, patched_oscil_$1_oct)
		define($2_freq, patched_oscil_$1_freq)
		define($2_phase, patched_oscil_$1_phase)
		define($2_phasor_out, patched_oscil_$1_phasor_out)
	])

])])])
])

define([patch_oscil_cos],[
# 1:id, 2:name, 3:out, 4:amp, 5:off, 6:oct, 7:freq, 8:phase
ifelse([$1],,,[
# id is required
	module cos patched_oscil_cos_$1
	patch_oscil($1,$2,$3,$4,$5,$6,$7,$8, 
		patched_oscil_cos_$1:in, patched_oscil_cos_$1:out)
	define(patched_oscil_cos_$1_out, patched_oscil_$1_out)
])
])

define([patch_oscil_impulse],[
# 1:id, 2:name, 3:out, 4:amp, 5:off, 6:oct, 7:freq, 8:phase
ifelse([$1],,,[
# id is required
	module trigger patched_oscil_impulse_$1

	init	patched_oscil_impulse_$1 count 1
	patch	patched_oscil_impulse_$1:1 0 # pulse happens at zero crossing

	patch_oscil($1,$2,$3,$4,$5,$6,$7,$8, 
		patched_oscil_impulse_$1:in, patched_oscil_impulse_$1:out)
	define(patched_oscil_impulse_$1_out, patched_oscil_$1_out)
])
])

define([patch_sh],[
# 1:id, 2:name, 3:out, 4:amp, 5:off, 6:trigger, 7:in
ifelse([$1],,,[
# id is required
	module	sh patched_sh_$1
	init	patched_sh_$1 count 1
	ifelse([$6],,,[ # if trigger is defined
		patch	patched_sh_$1:trigger $6
	])
	ifelse([$7],,,[ # if in is defined
		patch	patched_sh_$1:1 $7
	])
	patch_sigp($1,$2,$3,$4,$5,patched_sh_$1:1)
	define(patched_sh_$1_out,patched_sigp_$1_out)
	define(patched_sh_$1_in,patched_sh_$1:1)
	define(patched_sh_$1_trigger,patched_sh_$1:trigger)
	ifelse([$2],,,[ # if a name was specified, create the aliases
		define([$2_out], patched_sh_$1_out)
		define([$2_in], patched_sh_$1_in)
		define([$2_trigger], patched_sh_$1_trigger)
	])
])
])

define([patch_oscil_sh],[
# 1:id, 2:name, 3:out, 4:amp, 5:off, 6:oct, 7:freq, 8:phase, 9:in
ifelse([$1],,,[
# id is required
	patch_oscil_impulse($1,$2,,,,$6,$7,$8)
	patch_sh($1,$2,$3,$4,$5,patched_oscil_impulse_$1_out,$9)
	define(patched_oscil_sh_$1_out, patched_sh_$1_out)
])
])

define([patch_oscil_cossegs],[
# 1:id, 2:name, 3:out, 4:amp, 5:off, 6:oct, 7:freq, 8:phase, ...:val/dur pairs
ifelse([$1],,,[
# id is required
	module cossegs patched_oscil_cossegs_$1
	patch_many_by($1,$2,,,,patched_oscil_cossegs_$1,2,shift_many(8,$*))

	patch_oscil($1,$2,$3,$4,$5,$6,$7,$8, 
		patched_oscil_cossegs_$1:in, patched_oscil_cossegs_$1:out)
	define(patched_oscil_cossegs_$1_out, patched_oscil_$1_out)
])
])
